package com.googlecode.yoohoo.io.socket.stream;

import org.osgi.framework.BundleContext;

import com.googlecode.yoohoo.utils.Constants;
import com.googlecode.yoohoo.utils.OsgiUtils;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.IXmppParsingFactory;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.Iq;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.IqType;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.error.BadRequest;
import com.googlecode.yoohoo.xmppcore.protocol.stream.Session;
import com.googlecode.yoohoo.xmppcore.protocol.stream.error.InternalServerError;
import com.googlecode.yoohoo.xmppcore.stream.INegotiationContext;
import com.googlecode.yoohoo.xmppcore.utils.ErrorUtils;

/*import quicklinker.server.core.ServerContext;
import quicklinker.server.core.utils.AppConstants;
import quicklinker.server.core.utils.AppUtils;
import quicklinker.server.core.xmpp.AbstractXmppContext;
import quicklinker.server.core.xmpp.IError;
import quicklinker.server.core.xmpp.JabberId;
import quicklinker.server.core.xmpp.iq.Iq;
import quicklinker.server.core.xmpp.iq.IqType;
import quicklinker.server.core.xmpp.iq.TypeCheckIqExtensionParser;
import quicklinker.server.core.xmpp.stanza.ISession;
import quicklinker.server.core.xmpp.stanza.Session;
import quicklinker.server.core.xmpp.stream.errors.Conflict;
import quicklinker.server.core.xmpp.stream.errors.InternalServerError;*/


public class SessionEstablishmentNegotiant extends AbstractStreamNegotiant {
	private String jid;
	
	public void setJid(String jid) {
		this.jid = jid;
	}	
	
	@Override
	protected void doNegotiate(INegotiationContext context, String message) {
		if (jid == null)
			throw ErrorUtils.createProtocolException("Null jid", new InternalServerError());
		
		BundleContext bundleContext = ((NegotiationContext)context).getBundleContext();
		IXmppParsingFactory parsingFactory = OsgiUtils.getServiceInstance(bundleContext,
				IXmppParsingFactory.class, Constants.CONSTANT_XMPP_STREAM);
		
		Object obj = parsingFactory.parse(message);
		if (obj instanceof Iq) {
			Iq sessionRequest = (Iq)obj;
			if (!"set".equals(sessionRequest.getType())) {
				throw ErrorUtils.createProtocolException("Type of session establishment request must be 'set'.", new BadRequest());
			}
			
			Object sessionObj = sessionRequest.getObject();
			if (sessionObj instanceof Session) {				
				// TODO check and close activated session with the same resource id.
				/*JabberId jabberId;
				try {
					jabberId = JabberId.parseJidString(jid);
				} catch (InvalidJabberIdException e) {
					throw new RuntimeException("Invalid jid.", e);
				}*/
				/*ISession alreadyActivated = serverContext.getSession(jabberId);
				if (alreadyActivated != null) {
					IError conflict = new Conflict();
					try {
						alreadyActivated.write(conflict.toXml());
						alreadyActivated.syncClose();
					} catch (Exception e) {
						// ignore
					}
				}*/
				
				// TODO create new session
				//IoSession ioSession = ((NegotiationContext)context).getIoSession();
				/*ISession session = new Session(ioSession, serverContext, jabberId);
				ioSession.removeAttribute(AppConstants.KEY_NEGOTIATION_CONTEXT);
				ioSession.setAttribute(AppConstants.KEY_SESSION, session);
				serverContext.sessionCreated(session);*/
				
				context.setAttribute(NegotiationContext.KEY_NEGOTIATION_DONE, Boolean.TRUE); // set negotiation done
				
				Iq sessionResponse = new Iq();
				sessionResponse.setId(sessionRequest.getId());
				sessionResponse.setType(IqType.RESULT.toString());
				
				context.write(sessionResponse.toXml());
			} else {
				throw ErrorUtils.createProtocolException("Not a session establishment request.", new BadRequest());
			}
		} else {
			throw ErrorUtils.createProtocolException("Not a session establishment request.", new BadRequest());
		}
	}

	@Override
	protected NegotiationPhase getPhase() {
		return NegotiationPhase.SESSION_ESTABLISHMENT;
	}

}
